package xstr

import (
	"errors"
	"strings"
	"unicode"
	"unicode/utf8"
)

func IsEmpty(s *string) bool {
	if s == nil || len(*s) == 0 {
		return true
	}
	return false
}

func IsNotEmpty(s *string) bool {
	return !IsEmpty(s)
}

// 判断是否是字符（排除控制字符等）
func isChar(r rune) bool {
	return r != utf8.RuneError && r >= 32
}
func Capitalize(str string) string {
	if str == "" {
		return str
	}

	// 获取第一个 rune 和其大小
	r, size := utf8.DecodeRuneInString(str)
	if !isChar(r) {
		// 如果不是字母，直接返回原字符串
		return str
	}

	titleRune := unicode.ToTitle(r)

	if r == titleRune {
		return str
	}

	// 构建结果
	result := []rune{}
	result = append(result, titleRune)

	// 处理剩余部分
	for i := size; i < len(str); {
		r, size := utf8.DecodeRuneInString(str[i:])
		result = append(result, r)
		i += size
	}

	return string(result)
}

// IsHttp 是否为http(s)://开头
func IsHttp(link *string) bool {
	if link == nil {
		return false
	}
	return strings.HasPrefix(*link, "http://") || strings.HasPrefix(*link, "https://")
}

func ReplaceEach(text string, searchList []string, replacementList []string) (string, error) {
	return replaceEach(text, searchList, replacementList, true, 0)
}
func replaceEach(text string, searchList []string, replacementList []string, repeat bool, timeToLive int) (string, error) {
	if text == "" || len(searchList) == 0 || len(replacementList) == 0 {
		return text, nil
	}

	if len(searchList) != len(replacementList) {
		return "", errors.New("searchList and replacementList must be of the same length")
	}

	// 检查是否有环路导致死循环
	if timeToLive == 0 && repeat {
		searchSet := make(map[string]struct{})
		replacementSet := make(map[string]struct{})
		for _, s := range searchList {
			searchSet[s] = struct{}{}
		}
		for _, r := range replacementList {
			replacementSet[r] = struct{}{}
		}

		// 查找交集
		for s := range searchSet {
			if _, exists := replacementSet[s]; exists {
				return "", errors.New("Aborting to protect against StackOverflowError - output of one loop is the input of another")
			}
		}
	}

	noMoreMatchesForReplIndex := make([]bool, len(searchList))
	var buf strings.Builder
	start := 0
	textIndex := -1
	replaceIndex := -1

	// 寻找第一个出现的搜索词
	for i := 0; i < len(searchList); i++ {
		if noMoreMatchesForReplIndex[i] || searchList[i] == "" {
			continue
		}
		idx := strings.Index(text[start:], searchList[i])
		if idx == -1 {
			noMoreMatchesForReplIndex[i] = true
		} else {
			realIdx := start + idx
			if textIndex == -1 || realIdx < textIndex {
				textIndex = realIdx
				replaceIndex = i
			}
		}
	}

	if textIndex == -1 {
		return text, nil
	}

	// 构建结果
	for textIndex != -1 {
		buf.WriteString(text[start:textIndex])
		buf.WriteString(replacementList[replaceIndex])
		start = textIndex + len(searchList[replaceIndex])

		// 重置寻找状态
		textIndex = -1
		replaceIndex = -1

		for i := 0; i < len(searchList); i++ {
			if noMoreMatchesForReplIndex[i] || searchList[i] == "" {
				continue
			}
			idx := strings.Index(text[start:], searchList[i])
			if idx == -1 {
				noMoreMatchesForReplIndex[i] = true
			} else {
				realIdx := start + idx
				if textIndex == -1 || realIdx < textIndex {
					textIndex = realIdx
					replaceIndex = i
				}
			}
		}
	}

	// 添加剩余部分
	buf.WriteString(text[start:])

	result := buf.String()

	if !repeat {
		return result, nil
	}

	if timeToLive == 0 {
		return result, nil
	}

	// 递归替换
	return replaceEach(result, searchList, replacementList, repeat, timeToLive-1)
}

func StringToBool(str *string) bool {
	if str == nil {
		return false
	}
	return *str == "true" || *str == "1" || *str == "on" || *str == "yes" || *str == "y" || *str == "t" || *str == "T"
}
func EqualsAny(str string, values ...string) bool {
	for _, value := range values {
		if str == value {
			return true
		}
	}
	return false
}
